home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 422_02 / cutil / ppc.c < prev    next >
C/C++ Source or Header  |  1994-03-20  |  12KB  |  569 lines

  1. /*
  2.  * PPC.C - Pretty Printer for C
  3.  * Created from CB on SIMTEL20 by Richard Conn
  4.  *
  5.  * Compile command: cc ppc -fop
  6.  */
  7.  
  8. #include <stdio.h>
  9.  
  10. #define MAXBRAC 20        /* maximum number of open braces allowed */
  11. #define IFLEVEL 20        /* maximum number of nested IFs allowed */
  12.  
  13. int slevel[IFLEVEL];
  14. int spflg[MAXBRAC][IFLEVEL];
  15. int sind [MAXBRAC][IFLEVEL];
  16. int siflev[IFLEVEL];
  17. int sifflg[IFLEVEL];
  18. int clevel = 0;            /* Number of open braces */
  19. int iflev = 0;            /* Number of active IFs */
  20. int ifflg = -1;            /* Indicates if we have an active IF */
  21. int level = 0;
  22. int ind[IFLEVEL];        /* Indentation amount for a particular IF */
  23. int pflg[IFLEVEL];        /* Number of chars to indent for a particular IF */
  24. int eflg = 0;            /* We are in an ELSE? */
  25. int paren = 0;            /* Number of open parentheses */
  26. int tabcount = 4;        /* Number of characters to indent */
  27. char tabchar = ' ';        /* character to use for intenting */
  28. char lchar;
  29. char pchar;
  30. int aflg = 0;
  31. int stabs[MAXBRAC][IFLEVEL];
  32. int qflg = 0;
  33.  
  34. /* The following are reserved words used for special processing */
  35. char *wstr[] = {
  36.     "typedef",
  37.     "struct",
  38.     "union",
  39.     "int",
  40.     "char",
  41.     "unsigned",
  42.     "long",
  43.     "auto",
  44.     NULL
  45. };
  46. char *wrsvwds[] = {
  47.     "int",
  48.     "char",
  49.     "unsigned",
  50.     "long",
  51.     "auto",
  52.     NULL
  53. };
  54. char *wif[] = {
  55.     "if",
  56.     NULL
  57. };
  58. char *welse[] = {
  59.     "else",
  60.     NULL
  61. };
  62. char *wfor[] = {
  63.     "for",
  64.     NULL
  65. };
  66. char *wds[] = {
  67.     "case",
  68.     "default",
  69.     NULL
  70. };
  71.  
  72. /* J is the index for the next character in the STRING buffer
  73.    STRING is the buffer in which the output line is built */
  74. int j = 0;
  75. char string[400];
  76.  
  77. char cc;
  78. int sflg = 1;
  79. int bflg = 0;
  80. int peek = -1;
  81. int tabs = 0;
  82. int lastchar = ' ';
  83. int cin;
  84.  
  85. /* Input and output buffers */
  86. FILE *inpbuf;
  87. FILE *outbuf;
  88.  
  89. main(argc, argv)
  90. int argc;
  91. char *argv[];
  92. {
  93.     char bakfil[100]; /* name of current backup file */
  94.     int filno; /* number of current file */
  95.     int cont; /* local continuation flag */
  96.     int ct; /* count of local open parens */
  97.     int eflg; /* indicates we are in an ELSE */
  98.     int i;
  99.  
  100.     if (argc == 1) {
  101.         printf ("Pretty Printer for C, Beta Test Version 1.0\n\n");
  102.         printf ("Syntax: ppc [-s#] [-T#] filename.ext [filename.ext ...]\n");
  103.         printf ("Options:\n");
  104.         printf ("  -i[#]  Indent # SPACES for each level (default = 4)\n");
  105.         printf ("  -t[#]  Indent # TABS   for each level (default = 1)\n");
  106.         exit (0);
  107.     }
  108.  
  109.     /* Zero indentation indicator and indent character count buffers */
  110.     for (i=0; i<IFLEVEL; ++i) { 
  111.         ind[i] = 0; 
  112.         pflg[i] = 0; 
  113.     }
  114.  
  115.     /* Main Loop */
  116.     for (filno=1; filno < argc; ++filno) {
  117.  
  118.         /* Process next file (if not an option) */
  119.         if (*argv[filno] != '-') {
  120.             mkext (bakfil, argv[filno], "bak");
  121.             delete (bakfil);
  122.             rename (argv[filno], bakfil);
  123.             if ((inpbuf = fopen (bakfil, "r")) == NULL) {
  124.                 fprintf(stderr,"Unable to read: %s\n", bakfil);
  125.                 exit (1);
  126.             }
  127.             if ((outbuf = fopen (argv[filno], "w")) == NULL) {
  128.                 fprintf(stderr,"Unable to write: %s\n", argv[filno]);
  129.                 exit (1);
  130.             }
  131.             fprintf (stderr, "Pretty Printing %s\n", argv[filno]);
  132.             while ( (cin = getchr()) != EOF) {
  133.                 switch(cin) {
  134.                 case ' ':
  135.                 case '\t':
  136.                     if (lookup(welse) == 1) {
  137.                         gotelse ();
  138.                         if (sflg == 0 || j > 0) string[j++] =cin;
  139.                         putz ();
  140.                         sflg = 0;
  141.                         break;
  142.                     }
  143.                     if (sflg == 0 || j > 0) string[j++] =cin;
  144.                     break;
  145.                 case '\n':
  146.                     if ((eflg = lookup(welse)) == 1) gotelse();
  147.                     putz();
  148.                     fprintf (outbuf,"\n");
  149.                     sflg = 1;
  150.                     if (eflg == 1) {
  151.                         ++pflg[level];
  152.                         ++tabs;
  153.                     }
  154.                     else
  155.                         if (pchar == lchar)
  156.                             aflg = 1;
  157.                     break;
  158.                 case '{':
  159.                     if (lookup(welse) == 1) gotelse();
  160.                     siflev[clevel]= iflev;
  161.                     sifflg[clevel]= ifflg;
  162.                     iflev = ifflg = 0;
  163.                     ++clevel;
  164.                     if (sflg == 1 && pflg[level] != 0) {
  165.                         pflg[level]--;
  166.                         tabs--;
  167.                     }
  168.                     string[j++] =cin;
  169.                     putz ();
  170.                     getnl ();
  171.                     putz ();
  172.                     fprintf (outbuf,"\n");
  173.                     ++tabs;
  174.                     sflg = 1;
  175.                     if (pflg[level] > 0) {
  176.                         ind[level] = 1;
  177.                         ++level;
  178.                         slevel[level] = clevel;
  179.                     }
  180.                     break;
  181.                 case '}':
  182.                     clevel--;
  183.                     if ((iflev = siflev[clevel]-1) < 0) iflev = 0;
  184.                     ifflg = sifflg[clevel];
  185.                     putz ();
  186.                     tabs--;
  187.                     ptabs ();
  188.                     if ((peek = getchr()) == ';') {
  189.                         fprintf (outbuf, "%c;", cin);
  190.                         peek = -1;
  191.                     }
  192.                     else fprintf (outbuf,"%c", cin);
  193.                     getnl ();
  194.                     putz ();
  195.                     fprintf (outbuf,"\n");
  196.                     sflg = 1;
  197.                     if (clevel < slevel[level]) if (level > 0) level--;
  198.                     if (ind[level] != 0) {
  199.                         tabs -= pflg[level];
  200.                         pflg[level] =0;
  201.                         ind[level] = 0;
  202.                     }
  203.                     break;
  204.                 case '"':
  205.                 case '\'':
  206.                     string[j++] =cin;
  207.                     while ((cc = getc(inpbuf)) !=cin) {
  208.                         string[j++] =cc;
  209.                         if (cc == '\\') string[j++] = getc(inpbuf);
  210.                         if (cc == '\n') {
  211.                             putz();
  212.                             sflg = 1;
  213.                         }
  214.                     }
  215.                     string[j++] =cc;
  216.                     if (getnl() ==1) {
  217.                         lchar = cc;
  218.                         peek = '\n';
  219.                     }
  220.                     break;
  221.                 case ';':
  222.                     string[j++] =cin;
  223.                     putz ();
  224.                     if (pflg[level] > 0 && ind[level] == 0) {
  225.                         tabs -= pflg[level];
  226.                         pflg[level] = 0;
  227.                     }
  228.                     getnl ();
  229.                     putz ();
  230.                     fprintf (outbuf,"\n");
  231.                     sflg = 1;
  232.                     if (iflev > 0)
  233.                         if (ifflg == 1) {
  234.                             iflev--;
  235.                             ifflg = 0;
  236.                         }
  237.                         else iflev = 0;
  238.                     break;
  239.                 case '\\':
  240.                     string[j++] =cin;
  241.                     string[j++] =getchr();
  242.                     break;
  243.                 case '?':
  244.                     qflg = 1;
  245.                     string[j++] =cin;
  246.                     break;
  247.                 case ':':
  248.                     string[j++] =cin;
  249.                     if (qflg == 1) {
  250.                         qflg = 0;
  251.                         break;
  252.                     }
  253.                     if (lookup(wrsvwds) == 1) break;
  254.                     if (lookup(wds)== 0) {
  255.                         sflg = 0;
  256.                         putz ();
  257.                     }
  258.                     else {
  259.                         tabs--;
  260.                         putz ();
  261.                         ++tabs;
  262.                     }
  263.                     if ((peek = getchr()) == ';') {
  264.                         fprintf (outbuf, ";");
  265.                         peek = -1;
  266.                     }
  267.                     getnl ();
  268.                     putz ();
  269.                     fprintf (outbuf,"\n");
  270.                     sflg = 1;
  271.                     break;
  272.                 case '/':
  273.                     string[j++] =cin;
  274.                     if ((peek = getchr()) != '*') break;
  275.                     string[j++] = peek;
  276.                     peek = -1;
  277.                     comment ();
  278.                     break;
  279.                 case ')':
  280.                     paren--;
  281.                     string[j++] = cin;
  282.                     putz ();
  283.                     if (getnl() == 1) {
  284.                         peek = '\n';
  285.                         if (paren != 0) aflg = 1;
  286.                         else if (tabs > 0) {
  287.                             ++pflg[level];
  288.                             ++tabs;
  289.                             ind[level] = 0;
  290.                         }
  291.                     }
  292.                     break;
  293.                 case '#':
  294.                     string[j++] =cin;
  295.                     while ((cc = getc(inpbuf)) != '\n') string[j++] = cc;
  296.                     string[j++] =cc;
  297.                     sflg = 0;
  298.                     putz ();
  299.                     sflg = 1;
  300.                     break;
  301.                 case '(':
  302.                     string[j++] =cin;
  303.                     ++paren;
  304.                     if (lookup(wfor) == 1) {
  305.                         while ((cin = xgets()) != ';');
  306.                         ct = 0;
  307.                         cont = 1;
  308.                         while (cont) {
  309.                             while ((cin = xgets()) != ')') {
  310.                                 if (cin== '(') ++ct;
  311.                             }
  312.                             if(ct != 0) {
  313.                                 ct--;
  314.                             }
  315.                             else cont = 0;
  316.                         }
  317.                         paren--;
  318.                         putz ();
  319.                         if (getnl() ==1) {
  320.                             peek = '\n';
  321.                             ++pflg[level];
  322.                             ++tabs;
  323.                             ind[level] = 0;
  324.                         }
  325.                         break;
  326.                     }
  327.                     if (lookup(wif)== 1) {
  328.                         putz ();
  329.                         stabs[clevel][iflev] = tabs;
  330.                         spflg[clevel][iflev] = pflg[level];
  331.                         sind[clevel][iflev] = ind[level];
  332.                         ++iflev;
  333.                         ifflg = 1;
  334.                     }
  335.                     break;
  336.                 default:
  337.                     string[j++] = cin;
  338.                     if (cin != ',') lchar = cin;
  339.                     break;
  340.                 }
  341.             }
  342.             fclose (inpbuf);
  343.             fclose (outbuf);
  344.         }
  345.         /* Process an option */
  346.         else {
  347.             option (&argv[filno][1]);
  348.         }
  349.     }
  350. }
  351.  
  352. /* Process an option on the command line */
  353. option (item)
  354. char *item;
  355. {
  356.     switch (*item++) {
  357.     case 't' :
  358.     case 'T' :
  359.         tabchar = '\t';
  360.         tabcount = *item ? atoi (item) : 1;
  361.         break;
  362.     case 's' :
  363.     case 'S' :
  364.         tabchar = ' ';
  365.         tabcount = *item ? atoi (item) : 4;
  366.         break;
  367.     default :
  368.         fprintf (stderr, "Invalid option in command line: %s\n", item);
  369.         break;
  370.     }
  371. }
  372.  
  373. /*  Output leading indentation characters on the line */
  374. ptabs()
  375. {
  376.     int i, k;
  377.  
  378.     for (i = 0; i < tabs; ++i) { 
  379.         for (k = 0; k<tabcount; ++k)
  380.             putc(tabchar, outbuf);
  381.     }
  382. }
  383.  
  384. /* Return the next no